home *** CD-ROM | disk | FTP | other *** search
- /*************************************************************************
- * *
- * Preliminary *
- * Amiga AppShell (tm) *
- * *
- * Copyright (c) 1990,1991 Commodore-Amiga, Inc. All Rights Reserved. *
- * *
- * This software and information is proprietary, preliminary, and *
- * subject to change without notice. *
- * *
- * DISCLAIMER *
- * *
- * THIS SOFTWARE IS PROVIDED "AS IS". *
- * NO REPRESENTATIONS OR WARRANTIES ARE MADE WITH RESPECT TO THE *
- * ACCURACY, RELIABILITY, PERFORMANCE, CURRENTNESS, OR OPERATION *
- * OF THIS SOFTWARE, AND ALL USE IS AT YOUR OWN RISK. *
- * NEITHER COMMODORE NOR THE AUTHORS ASSUME ANY RESPONSIBILITY OR *
- * LIABILITY WHATSOEVER WITH RESPECT TO YOUR USE OF THIS SOFTWARE. *
- * *
- * Non-Disclosure *
- * *
- * This information is not to be disclosed to any other company, *
- * individual or party. Discussion is to be restricted to CBM *
- * approved discussion areas, such as the closed conferences on bix; *
- * amiga.cert, amiga.com, amiga.beta/appshell. *
- * *
- ************************************************************************
- */
-
- /* skeleton.c
- * Copyright (C) 1991 Commodore-Amiga, Inc.
- * Minimum requirements for an AppShell application.
- * Written by David N. Junod
- *
- */
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <exec/libraries.h>
- #include <intuition/intuition.h>
- #include <graphics/gfx.h>
- #include <libraries/gadtools.h>
- #include <libraries/appshell.h>
- #include <utility/tagitem.h>
- #include <clib/alib_protos.h>
- #include <clib/alib_stdio_protos.h>
- #include <clib/exec_protos.h>
- #include <clib/intuition_protos.h>
- #include <clib/graphics_protos.h>
- #include <clib/gadtools_protos.h>
- #include <clib/appshell_protos.h>
- #include <clib/utility_protos.h>
- #include <pragmas/appshell_pragmas.h>
- #include <string.h>
-
- #include "skeleton_rev.h"
-
- /* The AppShell maintains some basic information on the application. This
- * information would appear in the About requester, and in AppExchange. */
- #define APPBASE "SKELETON"
- #define APPNAME "Skeleton"
- #define APPVERS VERS
- #define APPCOPY "Copyright (C) 1991 Commodore-Amiga, Inc."
- #define APPAUTH "David N. Junod"
-
- STRPTR ver = VERSTAG;
-
- /* This structure contains all the data that our application will need.
- * Change to suit your application. */
- struct AppData
- {
- UBYTE ad_TmpText[128]; /* Temporary text buffer */
- LONG ad_Mode; /* Output mode */
- };
-
- /* Each public function gets a numeric ID assigned to it. You must
- * assign an ID to each one of your functions. Look at appshell.h for
- * standard function ID's for things like New, Open, Cut, Copy, Paste,
- * Quit, etc... */
- #define DUMMYID APSH_USER_ID
- #define CInitID (DUMMYID + 1L)
- #define OpenMainID (DUMMYID + 2L)
- #define SetModeID (DUMMYID + 3L)
- #define ErrorID (DUMMYID + 4L)
- #define GetInfoID (DUMMYID + 5L)
- #define User1ID (DUMMYID + 6L)
- #define User2ID (DUMMYID + 7L)
- #define LAST_ID (DUMMYID + 8L)
-
-
- /* These are the function prototypes for all the application implemented
- * functions used in this example. You must prototype all the functions
- * that your application is going use in the function table. */
- VOID CInitFunc (struct Hook *, struct AppInfo *, struct AppFunction *);
- VOID OpenMainFunc (struct Hook *, struct AppInfo *, struct AppFunction *);
- VOID SetModeFunc (struct Hook *, struct AppInfo *, struct AppFunction *);
- VOID GetInfoFunc (struct Hook *, struct AppInfo *, struct AppFunction *);
- VOID ErrorFunc (struct Hook *, struct AppInfo *, struct AppFunction *);
- VOID QuitFunc (struct Hook *, struct AppInfo *, struct AppFunction *);
-
- /* The AppShell will convert this array into function table entries and will
- * add them to the function table list. Using the APSHF_PRIVATE flag, we are
- * able to have functions that can't be triggered by the user. This
- * also defines the commands that are available through ARexx. Note that
- * the command parser is case-INSENSITIVE, but for readability, your
- * entries in this table should follow standard capitalization rules. */
- struct Funcs FTable[] =
- {
- {"Quit", QuitFunc, QuitID,},
- {"Error", ErrorFunc, ErrorID,},
-
- /* Functions with an argument template */
- {"SetMode", SetModeFunc, SetModeID, "MALE/S,FEMALE/S,ZOMBIE/S", 3L, NULL,},
- {"GetInfo", GetInfoFunc, GetInfoID, "STEM", 1L, NULL},
-
- /* These functions are private, and can not be accessed by the user */
- {"CInit", CInitFunc, CInitID, NULL, NULL, APSHF_PRIVATE},
- {"OpenMain", OpenMainFunc, OpenMainID, NULL, NULL, APSHF_PRIVATE},
-
- /* Experiment with ARexx scripts */
- {"User1", NO_FUNCTION, User1ID, },
- {"User2", NO_FUNCTION, User2ID, },
-
- /* Marks the end of the array */
- {NULL, NO_FUNCTION,}
- };
-
- /* All text used in the application must be defined in a text array. Then
- * referred to by numeric ID. */
- STRPTR Def_Text[] =
- {
- /* Padding */
- "",
-
- /* Window title */
- "Skeleton",
- #define TEXT_TITLE 1
-
- "Sex:",
- #define TEXT_LABEL 2
-
- /* Main window menus */
- #define TEXT_MENU 3
- " TITLE PROJECT LABEL Project",
- " ITEM QUIT LABEL Quit KEY Q CMD Quit",
-
- " TITLE EXTRAS LABEL Extras",
- " ITEM ERROR LABEL \"Show Error...\" KEY , CMD Error",
- " ITEM CMDSHELL LABEL \"Command Shell...\" KEY . CMD CmdShell",
-
- " TITLE USER LABEL User",
- " ITEM USER1 LABEL \"Macro 1\" KEY 1 CMD User1",
- " ITEM USER2 LABEL \"Macro 2\" KEY 2 CMD User2",
-
- " END",
-
- "Error: %s",
- #define ERROR_DISPLAY 12
-
- "Can't send stem variable",
- #define ERROR_CANT_RVI 13
-
- /* NULL termination is required */
- NULL
- };
-
-
- /* The following four tag arrays are GadTool tags for Window Environment
- * objects. */
- STRPTR output_data[] =
- {
- "Male",
- "Female",
- "Zombie",
- NULL
- };
-
- struct TagItem output_tags[] =
- {
- {GTCY_Labels, (LONG) output_data},
- {TAG_DONE,}
- };
-
- /* These are the objects that are going to be within our main window.
- * Note that the window itself is an object, and receives the SAME name
- * as in the WindowEnvironment tag list, APSH_NameTag. If you want
- * to specify any window tags, attach them to the window object. */
- struct Object objects[] =
- {
- {&objects[1], 0, 0, OBJ_Window, NULL, NULL, NULL, "Main", TEXT_TITLE,
- {0, 0, 0, 0}, NULL,},
-
- {NULL, 0, 0, OBJ_Cycle, SetModeID, NULL, NULL, "Mode", TEXT_LABEL,
- {44, 4, 101, 16}, output_tags,},
- };
-
- /* This is a Window Environment tag list. It describes a window. */
- struct TagItem mainenv[] =
- {
- {APSH_NameTag, (ULONG) "Main"},
- {APSH_Objects, (ULONG) objects},
- {APSH_TTMenu, TEXT_MENU},
- {APSH_WinAOpen, OpenMainID},
- {APSH_RefreshData, OpenMainID},
- {APSH_CloseWindow, QuitID},
- {TAG_DONE,}
- };
-
- /* Shared system libraries */
- extern struct Library *SysBase;
- extern struct Library *DOSBase;
- struct Library *GadToolsBase;
- struct Library *GfxBase;
- struct Library *IconBase;
- struct Library *IntuitionBase;
- struct Library *UtilityBase;
- struct Library *MySpecialBase;
-
- /* Library Environment:
- * This tag array is used to open and close the shared system libraries
- * needed by our application.
- */
- struct TagItem Our_Libs[] =
- {
- /* Minimum library version */
- {APSH_LibVersion, 36L},
-
- /* All libraries are required */
- {APSH_LibStatus, APSH_REQUIRED},
-
- /* Libraries to open */
- {APSH_GadTools, (ULONG) & GadToolsBase},
- {APSH_Gfx, (ULONG) & GfxBase},
- {APSH_Icon, (ULONG) & IconBase},
- {APSH_Intuition, (ULONG) & IntuitionBase},
- {APSH_Utility, (ULONG) & UtilityBase},
-
- /* The next library is optional */
- {APSH_LibStatus, APSH_OPTIONAL},
- {APSH_LibName, (ULONG) "myspecial.library"},
- {APSH_LibBase, (ULONG) & MySpecialBase},
- {TAG_DONE,}
- };
-
- /* Shell argument template */
- #define TEMPLATE "Male/S,Female/S,Zombie/S,PubScreen/K,PortName/K,Startup/K,NOGUI/S"
- #define OPT_MALE 0
- #define OPT_FEMALE 1
- #define OPT_ZOMBIE 2
- #define OPT_SCREENNAME 3
- #define OPT_PORTNAME 4
- #define OPT_STARTUP 5
- #define OPT_NOGUI 6
- #define OPT_COUNT 7
-
- /* ARexx user interface environment specification array */
- struct TagItem Handle_AREXX[] =
- {
- {APSH_Extens, (ULONG) "skel"},
- {APSH_Rating, APSH_OPTIONAL},
- {TAG_DONE,}
- };
-
- /* Command Shell user interface environment specification array */
- struct TagItem Handle_DOS[] =
- {
-
- /*
- * Presence of this tag, makes the Command Shell to stay closed until the user
- * sends a CMDSHELL OPEN command.
- */
- {APSH_Status, APSHP_INACTIVE},
- {APSH_Rating, APSH_REQUIRED},
- {TAG_DONE,}
- };
-
- /* These tags describe the Intuition user interface. */
- struct TagItem Handle_IDCMP[] =
- {
- {APSH_Rating, APSH_REQUIRED},
- {TAG_DONE,}
- };
-
- /* These tags describe the Simple IPC user interface. */
- struct TagItem Handle_SIPC[] =
- {
- {APSH_Rating, APSH_REQUIRED},
- {TAG_DONE,}
- };
-
- /* Application Environment:
- * Tell about our application */
- struct TagItem Our_App[] =
- {
- /* About the application */
- {APSH_AppName, (ULONG) APPNAME},
- {APSH_AppVersion, (ULONG) APPVERS},
- {APSH_AppCopyright, (ULONG) APPCOPY},
- {APSH_AppAuthor, (ULONG) APPAUTH},
-
- /* Trigger the library opening module */
- {APSH_OpenLibraries, (ULONG) Our_Libs},
-
- /* Specify the application function table */
- {APSH_FuncTable, (ULONG) FTable},
-
- /* Specify the application text table */
- {APSH_DefText, (ULONG) Def_Text},
-
- /* Tell how memory we need for our own data */
- {APSH_UserDataSize, sizeof (struct AppData)},
-
- /* Give our Shell startup argument template */
- {APSH_Template, (ULONG) TEMPLATE},
- {APSH_NumOpts, (ULONG) OPT_COUNT},
-
- /* Must always specify the SIPC user interface */
- {APSH_AddSIPC_UI, (ULONG) Handle_SIPC},
-
- /* Add an ARexx user interface */
- {APSH_AddARexx_UI, (ULONG) Handle_AREXX},
-
- /* Add a Command Shell user interface */
- {APSH_AddCmdShell_UI, (ULONG) Handle_DOS},
-
- /* Add an Intuition user interface */
- {APSH_AddIntui_UI, (ULONG) Handle_IDCMP},
-
- /* Specify a custom initialization routine */
- {APSH_AppInit, CInitID},
-
- {TAG_DONE,}
- };
-
- extern struct Library *AppShellBase;
-
- /* Handle messages between function handlers (this function is also
- * defined in support/misc.c). */
- BOOL
- HandlerFunc (struct AppInfo * ai, ULONG tags,...)
- {
-
- return (HandlerFuncA (ai, (struct TagItem *) & tags));
- }
-
- /* Sample initialization function */
- VOID CInitFunc (struct Hook *h, struct AppInfo *ai, struct AppFunction *af)
- {
- extern struct TagItem mainenv[];
- struct AppData *ad = ai->ai_UserData;
-
- /* See if any Shell arguments were specified */
- if (ai->ai_Options[OPT_MALE])
- {
- ad->ad_Mode = 0L;
- }
- else if (ai->ai_Options[OPT_FEMALE])
- {
- ad->ad_Mode = 1L;
- }
- else if (ai->ai_Options[OPT_ZOMBIE])
- {
- ad->ad_Mode = 2L;
- }
-
- /* Open the Main window */
- HandlerFunc (ai,
- APSH_Handler, "IDCMP",
- APSH_Command, APSH_MH_OPEN,
- APSH_WindowEnv, (ULONG) mainenv,
- TAG_DONE);
- }
-
- /* This function is called every time the Main window is opened. It
- * was specified by using the APSH_WinAOpen tag in the Main Window
- * Environemt tag array. I'm also 'cheating' and calling it everytime
- * I want to refresh the window and graphics. */
-
- VOID OpenMainFunc (struct Hook *h, struct AppInfo *ai, struct AppFunction *af)
- {
- struct AppData *ad = (struct AppData *) ai->ai_UserData;
- struct Window *win;
- struct Gadget *gad;
-
- /* Update the mode gadget */
- if (APSHGetGadgetInfo (ai, "Main", "Mode", (ULONG *) & win, (ULONG *) & gad))
- {
- /* Update the string gadget */
- GT_SetGadgetAttrs (gad, win, NULL, GTCY_Active, ad->ad_Mode, TAG_DONE);
- }
- }
-
- VOID SetModeFunc (struct Hook *h, struct AppInfo *ai, struct AppFunction *af)
- {
- struct AppData *ad = (struct AppData *) ai->ai_UserData;
- struct TagItem *attrs = af->af_Attrs;
- struct TagItem *tag;
- struct Gadget *gad;
- struct Window *win;
- LONG mode = (-1);
- struct Funcs *f;
-
- if (f = af->af_FE)
- {
- if (f->fe_Options[0])
- {
- ad->ad_Mode = mode = 0;
- }
- else if (f->fe_Options[1])
- {
- ad->ad_Mode = mode = 1;
- }
- else if (f->fe_Options[2])
- {
- ad->ad_Mode = mode = 2;
- }
- }
- /* Being set from the gadget */
- else if (tag = FindTagItem (APSH_MsgCode, attrs))
- {
- ad->ad_Mode = tag->ti_Data;
- }
-
- /* Update the gadget */
- if ((mode >= 0) &&
- (APSHGetGadgetInfo (ai, "Main", "Mode", (ULONG *) & win, (ULONG *) & gad)))
- {
- /* Update the string gadget */
- GT_SetGadgetAttrs (gad, win, NULL, GTCY_Active, mode, TAG_DONE);
- }
- }
-
- /* sample function returning an error */
- VOID ErrorFunc (struct Hook *h, struct AppInfo *ai, struct AppFunction *af)
- {
- STRPTR name = "Uh Oh!";
-
- /* sample error return */
- ai->ai_Pri_Ret = RETURN_ERROR;
- ai->ai_Sec_Ret = ERROR_DISPLAY;
- ai->ai_TextRtn = PrepText (ai, APSH_USER_ID, ai->ai_Sec_Ret, (int) name);
- }
-
- /* Given a screen pointer, determine the public screen name */
- VOID PubScreenName (struct Screen * scr, STRPTR buffer)
- {
- struct Screen *cs = NULL;
- struct List *publist;
- struct List copy_publist;
- struct PubScreenNode *psnode;
- struct PubScreenNode *copy_psnode;
-
- /* Initialize our variables */
- strcpy (buffer, "<private>");
- NewList (©_publist);
-
- /* Lock the public screen list */
- publist = LockPubScreenList ();
-
- /* and copy it */
- for (psnode = (struct PubScreenNode *) publist->lh_Head;
- psnode->psn_Node.ln_Succ;
- psnode = (struct PubScreenNode *) psnode->psn_Node.ln_Succ)
- {
- if (copy_psnode = AllocMem (sizeof (struct PubScreenNode), MEMF_CLEAR))
- {
- /* Copy the structure */
- *copy_psnode = *psnode;
-
- /*
- * ln_Name points to the public screen name, make your own copy
- */
- if (copy_psnode->psn_Node.ln_Name = AllocMem (strlen (psnode->psn_Node.ln_Name) + 1, MEMF_CLEAR))
- {
- strcpy (copy_psnode->psn_Node.ln_Name, psnode->psn_Node.ln_Name);
- }
-
- AddTail (©_publist, (struct Node *) copy_psnode);
- }
- }
-
- UnlockPubScreenList ();
-
- psnode = (struct PubScreenNode *) copy_publist.lh_Head;
- while ((copy_psnode = (struct PubScreenNode *) psnode->psn_Node.ln_Succ) &&
- (cs == NULL))
- {
- if (psnode->psn_Screen == scr)
- {
- strcpy (buffer, psnode->psn_Node.ln_Name);
- cs = psnode->psn_Screen;
- }
-
- if (psnode->psn_Node.ln_Name)
- {
- FreeMem (psnode->psn_Node.ln_Name, strlen (psnode->psn_Node.ln_Name) + 1);
- }
- Remove ((struct Node *) psnode);
- FreeMem (psnode, sizeof (struct PubScreenNode));
- psnode = copy_psnode;
- }
- }
-
- /* sample function returning ARexx stem variables */
- VOID GetInfoFunc (struct Hook *h, struct AppInfo *ai, struct AppFunction *af)
- {
- /* ARexx function prototypes */
- extern LONG SetRexxVar (struct RexxMsg *, UBYTE *, UBYTE *, LONG);
- extern LONG CheckRexxMsg (struct RexxMsg *);
-
- struct AppData *ad = (struct AppData *) ai->ai_UserData;
- UBYTE stem[128], value[140];
- struct MsgHandler *mh;
- struct RexxMsg *msg;
- struct Funcs *f;
- LONG kind;
-
- /* Build error string */
- ai->ai_Pri_Ret = RETURN_WARN;
- ai->ai_Sec_Ret = ERROR_CANT_RVI;
- ai->ai_TextRtn = PrepText (ai, APSH_USER_ID, ai->ai_Sec_Ret, NULL);
-
- /* Find out what type the current message is */
- if (GetAPSHAttr (ai, APSH_ActvMH, ai, &kind))
- {
- /* See if the current message is an ARexx message */
- if (kind == APSH_AREXX_ID)
- {
- /* Get a pointer to the current message */
- if (GetAPSHAttr (ai, APSH_ActvMessage, ai, &msg))
- {
- /* Check to see if we can set an RVI on this message. */
- if (CheckRexxMsg (msg))
- {
- /* Get the destination stem name */
- sprintf (stem, "%s.", ai->ai_BaseName);
- if (f = af->af_FE)
- {
- if (f->fe_Options[0])
- {
- strcpy (stem, (STRPTR) f->fe_Options[0]);
- }
- }
-
- /* Send the application version */
-
- /* Build the version variable */
- sprintf (ad->ad_TmpText, "%sVERSION", stem);
- strcpy (value, ai->ai_AppVersion);
-
- /* Set the RVI's */
- SetRexxVar (msg, ad->ad_TmpText, value, strlen (value));
-
- /* Send the current public screen name */
-
- /* Build the screen name variable */
- value[0] = 0;
- sprintf (ad->ad_TmpText, "%sSCREEN", stem);
- if (ai->ai_ScreenName)
- {
- strcpy (value, ai->ai_ScreenName);
- }
- else
- {
- PubScreenName (ai->ai_Screen, value);
- }
-
- /* Set the RVI's */
- SetRexxVar (msg, ad->ad_TmpText, value, strlen (value));
-
- /* Send the ARexx port name */
-
- /* Build the ARexx port name variable */
- sprintf (ad->ad_TmpText, "%sAREXX", stem);
-
- /* Build the value string */
- strcpy (value, "<unnamed>");
- if (GetAPSHAttr (ai, APSH_ARexxMH, ai, &mh) && mh)
- {
- strcpy (value, mh->mh_PortName);
- }
-
- /* Set the RVI's */
- SetRexxVar (msg, ad->ad_TmpText, value, strlen (value));
-
- /* Send the current mode */
-
- /* Build the variable name */
- sprintf (ad->ad_TmpText, "%sMODE", stem);
-
- /* Build the value string */
- strcpy (value, "<unset>");
- if (ad->ad_Mode == 0)
- strcpy (value, "Male");
- else if (ad->ad_Mode == 1)
- strcpy (value, "Female");
- else if (ad->ad_Mode == 2)
- strcpy (value, "Zombie");
-
- /* Set the RVI's */
- SetRexxVar (msg, ad->ad_TmpText, value, strlen (value));
-
- /* Return the name of the destination stem variable */
-
- /* Let them know what the stem variable is named */
- strcpy (ad->ad_TmpText, stem);
- ai->ai_Pri_Ret = RETURN_OK;
- ai->ai_Sec_Ret = NULL;
- ai->ai_TextRtn = ad->ad_TmpText;
- }
- }
- }
- }
- }
-
- /* Shutdown routine */
- VOID QuitFunc (struct Hook *h, struct AppInfo *ai, struct AppFunction *af)
- {
- /* Tell the AppShell that we're all done now. */
- ai->ai_Done = TRUE;
- }
-